
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>SQTracker API 测试报告</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { 
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
            line-height: 1.6; 
            color: #333; 
            background: #f5f5f5;
        }
        .container { max-width: 1200px; margin: 0 auto; padding: 20px; }
        .header { 
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
            color: white; 
            padding: 30px; 
            border-radius: 10px; 
            margin-bottom: 30px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
        }
        .header h1 { font-size: 2.5rem; margin-bottom: 10px; }
        .header .meta { opacity: 0.9; }
        
        .summary { 
            display: grid; 
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); 
            gap: 20px; 
            margin-bottom: 30px; 
        }
        .summary-card { 
            background: white; 
            padding: 20px; 
            border-radius: 8px; 
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            text-align: center;
        }
        .summary-card h3 { color: #666; margin-bottom: 10px; }
        .summary-card .value { font-size: 2rem; font-weight: bold; }
        .success { color: #27ae60; }
        .failed { color: #e74c3c; }
        .skipped { color: #f39c12; }
        .total { color: #3498db; }
        
        .section { 
            background: white; 
            margin-bottom: 30px; 
            border-radius: 8px; 
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        .section-header { 
            background: #f8f9fa; 
            padding: 20px; 
            border-bottom: 1px solid #dee2e6;
        }
        .section-content { padding: 20px; }
        
        .progress-bar { 
            background: #e9ecef; 
            border-radius: 4px; 
            overflow: hidden; 
            height: 20px; 
            margin: 10px 0;
        }
        .progress-fill { 
            height: 100%; 
            transition: width 0.3s ease;
        }
        .progress-success { background: #27ae60; }
        
        .suite { 
            border: 1px solid #dee2e6; 
            border-radius: 6px; 
            margin-bottom: 20px; 
            overflow: hidden;
        }
        .suite-header { 
            padding: 15px; 
            background: #f8f9fa; 
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .suite-header:hover { background: #e9ecef; }
        .suite-content { padding: 15px; display: none; }
        .suite-content.active { display: block; }
        
        .test-case { 
            padding: 10px; 
            border-left: 4px solid #dee2e6; 
            margin-bottom: 10px;
            background: #f8f9fa;
        }
        .test-case.passed { border-left-color: #27ae60; background: #d4edda; }
        .test-case.failed { border-left-color: #e74c3c; background: #f8d7da; }
        .test-case.skipped { border-left-color: #f39c12; background: #fff3cd; }
        
        .status-badge { 
            padding: 4px 8px; 
            border-radius: 4px; 
            font-size: 0.8rem; 
            font-weight: bold; 
            text-transform: uppercase;
        }
        .status-passed { background: #d4edda; color: #155724; }
        .status-failed { background: #f8d7da; color: #721c24; }
        
        .coverage-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
        }
        
        .coverage-item {
            text-align: center;
            padding: 15px;
            border-radius: 6px;
            background: #f8f9fa;
        }
        
        .coverage-value {
            font-size: 1.5rem;
            font-weight: bold;
            margin-bottom: 5px;
        }
        
        .coverage-high { color: #27ae60; }
        .coverage-medium { color: #f39c12; }
        .coverage-low { color: #e74c3c; }
        
        .toggle-icon { 
            transition: transform 0.3s ease; 
        }
        .toggle-icon.rotated { 
            transform: rotate(90deg); 
        }
        
        @media (max-width: 768px) {
            .container { padding: 10px; }
            .header h1 { font-size: 2rem; }
            .summary { grid-template-columns: 1fr; }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🎯 SQTracker API 测试报告</h1>
            <div class="meta">
                <p>📅 生成时间: 2025/6/11 00:09:14</p>
                <p>⏱️ 测试耗时: 6864ms</p>
                <p>📈 通过率: 100.00%</p>
                <p>📊 语句覆盖率: 0%</p>
            </div>
        </div>

        <!-- 汇总统计 -->
        <div class="summary">
            <div class="summary-card">
                <h3>总测试数</h3>
                <div class="value total">60</div>
            </div>
            <div class="summary-card">
                <h3>通过</h3>
                <div class="value success">60</div>
            </div>
            <div class="summary-card">
                <h3>失败</h3>
                <div class="value failed">0</div>
            </div>
            <div class="summary-card">
                <h3>跳过</h3>
                <div class="value skipped">0</div>
            </div>
        </div>

        <!-- 总体进度 -->
        <div class="section">
            <div class="section-header">
                <h2>📊 测试进度</h2>
            </div>
            <div class="section-content">
                <div class="progress-bar">
                    <div class="progress-fill progress-success" style="width: 100.00%"></div>
                </div>
                <p>通过率: 100.00% (60/60)</p>
            </div>
        </div>

        

        <!-- 测试套件详情 -->
        <div class="section">
            <div class="section-header">
                <h2>🧪 测试套件详情 (1 个套件)</h2>
            </div>
            <div class="section-content">
                
        <div class="suite">
            <div class="suite-header">
                <div>
                    <strong>C:\job\React\sqtracker_2\group-11--pt-site-front-end\api\tests\api.test.js</strong>
                    <span class="status-badge status-passed">passed</span>
                    <span style="margin-left: 10px; color: #666;">
                        undefined/NaN 通过 (0%)
                    </span>
                </div>
                <div>
                    <span style="color: #666; margin-right: 10px;">6864ms</span>
                    <span class="toggle-icon">▶</span>
                </div>
            </div>
            <div class="suite-content">
                
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功注册新用户</span>
                <span style="color: #666; font-size: 0.9rem;">132ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝重复的用户名</span>
                <span style="color: #666; font-size: 0.9rem;">11ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功登录有效用户</span>
                <span style="color: #666; font-size: 0.9rem;">71ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝错误密码</span>
                <span style="color: #666; font-size: 0.9rem;">63ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝不存在的用户</span>
                <span style="color: #666; font-size: 0.9rem;">8ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该发起密码重置</span>
                <span style="color: #666; font-size: 0.9rem;">7ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>对不存在邮箱也应返回200（安全考虑）</span>
                <span style="color: #666; font-size: 0.9rem;">10ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户基本信息</span>
                <span style="color: #666; font-size: 0.9rem;">51ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>管理员应该能看到更多用户信息</span>
                <span style="color: #666; font-size: 0.9rem;">23ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户统计信息</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户角色</span>
                <span style="color: #666; font-size: 0.9rem;">11ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功更改密码</span>
                <span style="color: #666; font-size: 0.9rem;">360ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝错误的当前密码</span>
                <span style="color: #666; font-size: 0.9rem;">65ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户邀请列表</span>
                <span style="color: #666; font-size: 0.9rem;">10ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该允许购买邀请</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回种子详细信息</span>
                <span style="color: #666; font-size: 0.9rem;">14ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回404对不存在的种子</span>
                <span style="color: #666; font-size: 0.9rem;">11ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回最新种子列表</span>
                <span style="color: #666; font-size: 0.9rem;">17ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回搜索结果</span>
                <span style="color: #666; font-size: 0.9rem;">20ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该支持分类筛选</span>
                <span style="color: #666; font-size: 0.9rem;">17ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该支持标签筛选</span>
                <span style="color: #666; font-size: 0.9rem;">17ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功投赞成票</span>
                <span style="color: #666; font-size: 0.9rem;">18ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功投反对票</span>
                <span style="color: #666; font-size: 0.9rem;">17ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝无效投票类型</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功取消投票</span>
                <span style="color: #666; font-size: 0.9rem;">16ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功添加评论</span>
                <span style="color: #666; font-size: 0.9rem;">31ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝空评论</span>
                <span style="color: #666; font-size: 0.9rem;">14ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回所有标签列表</span>
                <span style="color: #666; font-size: 0.9rem;">15ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功创建评分</span>
                <span style="color: #666; font-size: 0.9rem;">16ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该能更新已有评分</span>
                <span style="color: #666; font-size: 0.9rem;">13ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝无效评分（超出范围）</span>
                <span style="color: #666; font-size: 0.9rem;">21ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回种子的所有评分</span>
                <span style="color: #666; font-size: 0.9rem;">20ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户的所有评分</span>
                <span style="color: #666; font-size: 0.9rem;">15ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回种子评分统计</span>
                <span style="color: #666; font-size: 0.9rem;">14ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回用户对特定种子的评分</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>未评分时应返回404</span>
                <span style="color: #666; font-size: 0.9rem;">14ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回推荐列表</span>
                <span style="color: #666; font-size: 0.9rem;">13ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该支持count参数</span>
                <span style="color: #666; font-size: 0.9rem;">13ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回相似种子推荐</span>
                <span style="color: #666; font-size: 0.9rem;">25ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该保存用户偏好</span>
                <span style="color: #666; font-size: 0.9rem;">24ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝空偏好</span>
                <span style="color: #666; font-size: 0.9rem;">11ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功创建请求</span>
                <span style="color: #666; font-size: 0.9rem;">30ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回请求列表</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回特定请求详情</span>
                <span style="color: #666; font-size: 0.9rem;">10ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该成功添加评论</span>
                <span style="color: #666; font-size: 0.9rem;">22ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该返回模糊搜索结果</span>
                <span style="color: #666; font-size: 0.9rem;">12ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝过短的查询</span>
                <span style="color: #666; font-size: 0.9rem;">8ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>普通用户不应该能访问统计信息</span>
                <span style="color: #666; font-size: 0.9rem;">9ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>管理员应该能封禁用户</span>
                <span style="color: #666; font-size: 0.9rem;">78ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>普通用户不应该能封禁用户</span>
                <span style="color: #666; font-size: 0.9rem;">9ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>管理员应该能解封用户</span>
                <span style="color: #666; font-size: 0.9rem;">15ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>管理员应该能切换种子免费下载状态</span>
                <span style="color: #666; font-size: 0.9rem;">15ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>普通用户不应该能切换免费下载状态</span>
                <span style="color: #666; font-size: 0.9rem;">8ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝无效用户ID的announce</span>
                <span style="color: #666; font-size: 0.9rem;">10ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该拒绝未验证邮箱用户的announce</span>
                <span style="color: #666; font-size: 0.9rem;">69ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该处理未认证的请求</span>
                <span style="color: #666; font-size: 0.9rem;">6ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>应该处理不存在的路由</span>
                <span style="color: #666; font-size: 0.9rem;">9ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>用户注册应该验证必需字段</span>
                <span style="color: #666; font-size: 0.9rem;">5ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>种子上传应该验证必需字段</span>
                <span style="color: #666; font-size: 0.9rem;">10ms</span>
            </div>
        </div>
      
        <div class="test-case passed">
            <div style="display: flex; justify-content: space-between; align-items: center;">
                <span>公告创建应该验证必需字段</span>
                <span style="color: #666; font-size: 0.9rem;">7ms</span>
            </div>
        </div>
      
            </div>
        </div>
      
            </div>
        </div>
    </div>

    <script>
        // 切换测试套件显示
        document.querySelectorAll('.suite-header').forEach(header => {
            header.addEventListener('click', () => {
                const content = header.nextElementSibling;
                const icon = header.querySelector('.toggle-icon');
                
                content.classList.toggle('active');
                icon.classList.toggle('rotated');
            });
        });
    </script>
</body>
</html>